home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / wb / mbm.lzh / switcher.c < prev   
C/C++ Source or Header  |  1992-04-13  |  7KB  |  250 lines

  1. /*
  2.  * Switcher.c - bring up a requester listing screens & windows, and bring
  3.  * the one selected to the front. Shut down on window deactivation.
  4.  * ===build
  5.  * % lc -Lcdn -v -tr -O -mcs -r -rr -b -cfsu -d0 switcher ; output= switcher inputs= switcher.c
  6.  * ===endbuild
  7.  */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11. #include <intuition/intuition.h>
  12. #include <intuition/intuitionbase.h>
  13. #include <intuition/gadgetclass.h>
  14. #include <graphics/gfxmacros.h>
  15. #include <graphics/gfxbase.h>
  16. #include <utility/tagitem.h>
  17. #include <clib/macros.h>
  18. #include <string.h>
  19.  
  20. #include <libraries/gadtools.h>
  21.  
  22. #include <clib/exec_protos.h>
  23. #include <pragmas/exec.h>
  24. #include <clib/graphics_protos.h>
  25. #include <pragmas/graphics.h>
  26. #include <clib/intuition_protos.h>
  27. #include <pragmas/intuition.h>
  28. #include <clib/gadtools_protos.h>
  29. #include <pragmas/gadtools.h>
  30.  
  31. extern struct GfxBase *GfxBase = NULL;
  32. extern struct IntuitionBase *IntuitionBase = NULL;
  33. extern struct Library *GadToolsBase = NULL;
  34.  
  35. /*
  36.  * Test code; generate a main to call the switcher.
  37.  */
  38. void
  39. _main(char *x) {
  40.     void switcher(void);
  41.  
  42.     /* Open libraries */
  43.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 36L);
  44.     IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 36L);
  45.     GadToolsBase = OpenLibrary("gadtools.library", 36L);
  46.  
  47.     /* Run the switcher */
  48.     if (GfxBase && IntuitionBase && GadToolsBase) switcher();
  49.  
  50.     /* and shut them down */
  51.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  52.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  53.     if (GfxBase) CloseLibrary(GfxBase);
  54.     }
  55.  
  56. static struct TagItem windowtags[] = { WA_AutoAdjust, TRUE, TAG_DONE } ;
  57. static struct ExtNewWindow mynewwin =
  58. {
  59.     0, 0,        /* LeftEdge, TopEdge */
  60.     0, 0,        /* Width, Height filled in later */
  61.     -1, -1,             /* DetailPen, BlockPen */
  62.     IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_REFRESHWINDOW | IDCMP_INACTIVEWINDOW,
  63.     WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_SIMPLE_REFRESH | WFLG_NW_EXTENDED,
  64.     NULL,        /* FirstGadget */
  65.     NULL,        /* CheckMark */
  66.     NULL,        /* Title */
  67.     NULL,        /* Screen */
  68.     NULL,        /* BitMap */    
  69.     0, 0,        /* MinWidth, MinHeight */
  70.     0, 0,        /* MaxWidth, MaxHeight */
  71.     CUSTOMSCREEN,    /* Type */
  72.     windowtags        /* Tags */
  73. };
  74.  
  75. struct MBMNode {
  76.     struct Node m_Node;
  77.     struct Window *m_Window;
  78.     struct Screen *m_Screen;
  79.     };
  80.  
  81. /* My globals */
  82. static struct Remember *RKey = NULL;
  83.  
  84. #define MAXNAMELEN    40
  85.  
  86. static USHORT
  87. AddName(struct Screen *s, struct Window *w, struct List *lh) {
  88.     struct MBMNode *node;
  89.     char namebuf[MAXNAMELEN + 1];
  90.  
  91.     if (w) {
  92.     if (!w->Title || !*w->Title) return 0;
  93.     *namebuf = ' ';
  94.     strncpy(namebuf + 1, w->Title, MAXNAMELEN - 1);
  95.     }
  96.     else {
  97.     *namebuf = '\273';
  98.     if (s->DefaultTitle) strncpy(namebuf + 1, s->DefaultTitle, MAXNAMELEN - 1);
  99.     else namebuf[1] = '\0';
  100.     }
  101.     namebuf[MAXNAMELEN] = '\0';    /* Insurance */
  102.  
  103.     node = (struct MBMNode *)AllocRemember(&RKey, sizeof(struct MBMNode), MEMF_CLEAR);
  104.     node->m_Node.ln_Name = strdup(namebuf);
  105.     node->m_Window = w;
  106.     node->m_Screen = s;
  107.     AddTail(lh, node);
  108.     return strlen(namebuf);
  109.     }
  110.  
  111. /* 
  112.  * Gadgets Finds the data to go in the gadget, and set various sizes based on
  113.  * that data.
  114.  */
  115. static struct Gadget *
  116. Gadgets(struct Gadget **glistptr, void *vi, struct TextFont *f, struct List *lh)
  117. {
  118.     struct TagItem gadtags[2] ;
  119.     void NewList(struct List *);
  120.     struct NewGadget ng;
  121.     struct Gadget *gad;
  122.     LONG lock;
  123.     USHORT tmplen, longname = 0, length;
  124.     struct Screen *s;
  125.     struct Window *w;
  126.  
  127.     gad = CreateContext(glistptr);
  128.  
  129.     NewList(lh);
  130.     lock = LockIBase(0L);
  131.     for (s = IntuitionBase -> FirstScreen, length = 0; s;
  132.       s = s -> NextScreen, length += 1) {
  133.     if ((tmplen = AddName(s, NULL, lh)) > longname) longname = tmplen;
  134.     for (w = s->FirstWindow; w; w = w -> NextWindow) {
  135.         if ((tmplen = AddName(s, w, lh)) > longname) longname = tmplen;
  136.         if (tmplen) length += 1;
  137.         }
  138.     }
  139.     UnlockIBase(lock);
  140.  
  141.     if (length > 20) length = 20;
  142.     ng.ng_Width = mynewwin.Width = f->tf_XSize * (MAXNAMELEN + 2);
  143.     ng.ng_Height = mynewwin.Height = f->tf_YSize * length + 6;
  144.     ng.ng_LeftEdge = 0;
  145.     ng.ng_TopEdge = 0;
  146.     ng.ng_GadgetText = NULL;
  147.     ng.ng_TextAttr = NULL;
  148.     ng.ng_Flags = NG_HIGHLABEL|PLACETEXT_LEFT;
  149.     ng.ng_VisualInfo = vi;
  150.     gadtags[0].ti_Tag = GTLV_Labels;
  151.     gadtags[0].ti_Data = (ULONG) lh;
  152.     gadtags[1].ti_Tag = TAG_DONE;
  153.     gad = CreateGadgetA(LISTVIEW_KIND, gad, &ng, gadtags);
  154.  
  155.     /* Finsh tweaking the window */
  156.     mynewwin.LeftEdge = IntuitionBase->ActiveScreen->MouseX - (mynewwin.Width / 2);
  157.     if (mynewwin.LeftEdge < 0) mynewwin.LeftEdge = 0;
  158.     mynewwin.TopEdge = IntuitionBase->ActiveScreen->MouseY - (mynewwin.Height / 2);
  159.     if (mynewwin.TopEdge < 0) mynewwin.TopEdge = 0;
  160.     return(gad);
  161.     }
  162.  
  163. /*
  164.  * Start of the switcher proper.
  165.  */
  166. static void
  167. switcher(void) {
  168.     struct List lh;
  169.     BOOL terminated = FALSE;
  170.     struct Screen *s = NULL;
  171.     struct Window *w;
  172.     struct Gadget *glist = NULL;
  173.     struct Window *mywin = NULL;
  174.     void *vi = NULL;
  175.     struct IntuiMessage *imsg;
  176.     struct Gadget *gad;
  177.     ULONG imsgClass;
  178.     UWORD imsgCode, CountCode;
  179.     LONG  lock;
  180.     struct MBMNode *NodeCode;
  181.  
  182.     /*
  183.      * This probably all ought to happen inside a LockIBase, but...
  184.      */
  185.  
  186.     /* Information needed to open the window */
  187.     s = IntuitionBase->ActiveScreen;
  188.     if (!(vi = GetVisualInfoA(s, NULL))) goto out;
  189.     if (!Gadgets(&glist, vi, s->RastPort.Font, &lh)) goto out;
  190.     mynewwin.FirstGadget = glist;
  191.     mynewwin.Screen = s;
  192.  
  193.     /* Open the window, and render it */
  194.     if (!(mywin = OpenWindow(&mynewwin))) goto out;
  195.     GT_RefreshWindow(mywin, NULL);
  196.  
  197.     while (!terminated) {
  198.     Wait (1 << mywin->UserPort->mp_SigBit);
  199.     /* GT_GetIMsg() returns a cooked-up IntuiMessage with
  200.      * more friendly information for complex gadget classes.  Use
  201.      * it wherever you get IntuiMessages:
  202.      */
  203.     while ((!terminated) && (imsg = GT_GetIMsg(mywin->UserPort)))
  204.     {
  205.         imsgClass = imsg->Class;
  206.         imsgCode = imsg->Code;
  207.         /* Presuming a gadget, of course, but no harm... */
  208.         gad = (struct Gadget *)imsg->IAddress;
  209.         /* Use the toolkit message-replying function here... */
  210.         GT_ReplyIMsg(imsg);
  211.         switch (imsgClass)
  212.         {
  213.         case IDCMP_GADGETUP:
  214.             for (CountCode = imsgCode, NodeCode = (struct MBMNode *) lh.lh_Head; CountCode--;
  215.             NodeCode = (struct MBMNode *) NodeCode->m_Node.ln_Succ)
  216.                 ;
  217.             lock = LockIBase(0);
  218.             for (s = IntuitionBase->FirstScreen; s; s = s->NextScreen)
  219.                 if (s == NodeCode->m_Screen)
  220.                 break;
  221.             if (!s) {
  222.                 UnlockIBase(lock);
  223.             break;
  224.             }
  225.             ScreenToFront(s);
  226.             for (w = s->FirstWindow; w; w = w->NextWindow)
  227.                 if (w == NodeCode->m_Window) break;
  228.             if (w) WindowToFront(w);
  229.             UnlockIBase(lock);
  230.             terminated = 1;
  231.             break;
  232.  
  233.         case IDCMP_INACTIVEWINDOW:
  234.             terminated = 1;
  235.             break;
  236.  
  237.         case IDCMP_REFRESHWINDOW:
  238.             GT_BeginRefresh(mywin);
  239.             GT_EndRefresh(mywin, TRUE);
  240.             break;
  241.         }
  242.     }
  243.     }
  244. out:
  245.     if (mywin) CloseWindow(mywin);
  246.     FreeVisualInfo(vi);
  247.     FreeGadgets(glist);
  248.     if (RKey) FreeRemember(&RKey, TRUE);
  249. }
  250.